package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
	"ebbflow/src/consensus"
	"ebbflow/src/message"

	"ebbflow/src/communication"
)

const (
	helpText_ebbflow_client = `
EbbFlow Protocol Client
Usage: ebbflow_client [ClientID] [BatchSize] [MessageCount]
`
)

var (
	clientID     = flag.Int("id", 100, "Client ID")
	batchSize    = flag.Int("batch", 500, "Batch size")
	messageCount = flag.Int("count", 10000, "Number of messages")
	txSize       = flag.Int("txsize", 250, "Transaction size in bytes")
	verbose      = flag.Bool("v", false, "Verbose logging")
)

func main() {
	flag.Parse()
	
	log.Printf("Starting EbbFlow Protocol Client")
	log.Printf("Client ID: %d, Batch Size: %d, Message Count: %d, TX Size: %d bytes", 
		*clientID, *batchSize, *messageCount, *txSize)
	
	// Create communication channels
	msgInCh := make(chan message.ReplicaMessage, 1000)
	msgOutCh := make(chan message.ReplicaMessage, 1000)
	
	// Create integrated consensus (client mode)
	consensus := consensus.NewEbbFlowConsensus(
		*clientID, 6, 1, // Use default node configuration
		msgInCh, msgOutCh,
	)
	
	// Start consensus
	if err := consensus.Start(); err != nil {
		log.Fatalf("Failed to start consensus: %v", err)
	}
	
	// Start message handling
	go handleOutgoingMessages(msgOutCh)
	go handleIncomingMessages(msgInCh)
	
	// Start performance monitoring
	go monitorPerformance(consensus)
	
	// Start transaction submission
	go submitTransactions(consensus)
	
	// Handle shutdown signals
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
	
	log.Printf("EbbFlow client started successfully")
	
	// Wait for shutdown signal
	<-sigChan
	log.Printf("Shutting down EbbFlow client...")
	
	// Stop consensus
	consensus.Stop()
	
	log.Printf("EbbFlow client stopped")
}

func handleOutgoingMessages(msgOutCh <-chan message.ReplicaMessage) {
	for msg := range msgOutCh {
		// In a real implementation, this would send the message over the network
		if *verbose {
			log.Printf("Sending message: Type=%v, Instance=%d, Source=%d", 
				msg.Mtype, msg.Instance, msg.Source)
		}
		
		// Simulate network delay (reduced for higher throughput)
		// Network delay removed - using real network communication
	}
}

// handleIncomingMessages 真实的消息处理函数
func handleIncomingMessages(msgInCh chan<- message.ReplicaMessage) {
	// 使用gRPC接收真实消息
	// 这里将集成waterbear的receiver组件
	// 暂时保持空实现，等待gRPC集成
	log.Printf("Real message handling - gRPC integration pending")
}
	}
}

func submitTransactions(consensus *consensus.EbbFlowConsensus) {
	log.Printf("Starting transaction submission")
	
	startTime := time.Now()
	submittedCount := 0
	
	// Create transaction data of specified size
	txData := make([]byte, *txSize)
	for i := range txData {
		txData[i] = byte(i % 256) // Fill with pattern data
	}
	
	for i := 0; i < *messageCount; i++ {
		// Create transaction with specified size
		tx := make([]byte, *txSize)
		copy(tx, txData)
		// Add unique identifier
		copy(tx[:8], []byte(fmt.Sprintf("%08d", i)))
		
		// Submit transaction
		if err := consensus.SubmitTransaction(tx); err != nil {
			log.Printf("Failed to submit transaction %d: %v", i, err)
			continue
		}
		
		submittedCount++
		
		// Batch processing - submit in batches
		if *batchSize > 1 && submittedCount%*batchSize == 0 {
			// Network delay removed - using real network communication // Reduced delay between batches
		}
		
		// Reduced rate limiting for higher throughput
		if *batchSize == 1 {
			// Network delay removed - using real network communication // Much smaller delay for single transactions
		}
	}
	
	elapsed := time.Since(startTime)
	tps := float64(submittedCount) / elapsed.Seconds()
	
	log.Printf("Transaction submission completed")
	log.Printf("Submitted: %d transactions in %.2f seconds", submittedCount, elapsed.Seconds())
	log.Printf("Submission TPS: %.2f", tps)
	log.Printf("Batch Size: %d, TX Size: %d bytes", *batchSize, *txSize)
}

func monitorPerformance(consensus *consensus.EbbFlowConsensus) {
	ticker := time.NewTicker(2 * time.Second)
	// Ticker stop removed - using real message handling
	
	// Ticker loop removed - using real message handling
	// Real message handling will be implemented here
		status := consensus.GetProtocolStatus()
		log.Printf("Client Performance: ID=%d, Epoch=%v, Consensus=%v, TPS=%v", 
			status["node_id"], status["current_epoch"], 
			status["ebbflow/src/consensus_count"], status["tps"])
	}
}
